package edu.je.prs.Service;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huaban.analysis.jieba.JiebaSegmenter;
import com.huaban.analysis.jieba.SegToken;
import com.junqson.je.common.constant.AppRedisKey;
import com.junqson.je.common.model.ApiResult;
import edu.je.prs.Mapper.AnalyseDataMapper;
import edu.je.prs.Mapper.StationInfoMapper;
import edu.je.prs.Model.StationInfo;
import edu.je.prs.util.EchartsUtil;
import edu.je.prs.vo.EchartsVo;
import edu.je.prs.vo.FrequencyArraysVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @author: Anhlaidh
 * @date: 2021-03-17 16:15
 */
@Service
public class FrequencyService {
    @Autowired
    StationInfoMapper stationInfoMapper;
    @Autowired
    AnalyseDataMapper analyseDataMapper;
    @Autowired
    StringRedisTemplate redisTemplate;
    JiebaSegmenter segmenter = new JiebaSegmenter();


    private static HashSet<String> SpringFamily = new HashSet<String>(Arrays.asList(new String[]{"boot", "cloud", "security", "core"}));

    public Set<String> getSkillsById(int id) {
        HashMap<String, Integer> map = new HashMap<>();
        getSkillFrequency(segmenter, stationInfoMapper.selectByPrimaryKey(id).getDetail(), map);
        return map.keySet();
    }


    public HashMap<String, Integer> getAllSkillFrequency() {

        String s = redisTemplate.opsForValue().get(AppRedisKey.ALL_SKILL_FREQUENCY);

        if (s!=null) {
            return JSON.parseObject(s, HashMap.class);
        }

        HashMap<String, Integer> map = new HashMap<>();
        List<StationInfo> list = getAllStationList();
        for (int i = 0; i < list.size(); i++) {
            String detail = list.get(i).getDetail();
            getSkillFrequency(segmenter, detail, map);
        }
        Set<Map.Entry<String, Integer>> entries = map.entrySet();

        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
        HashMap<String, Integer> result = new HashMap<>();
        while (iterator.hasNext()) {
            Map.Entry<String, Integer> entry = iterator.next();
            //TODO 等脚本过滤html标签
            if (entry.getValue() < 60 || entry.getKey().length() < 2) {
                continue;
            }
            result.put(entry.getKey(), entry.getValue());
        }
        redisTemplate.opsForValue().set(AppRedisKey.ALL_SKILL_FREQUENCY,JSON.toJSONString(result),1, TimeUnit.HOURS);


        return result;
    }

    private void getSkillFrequency(JiebaSegmenter segmenter, String str, HashMap<String, Integer> map) {

        List<SegToken> tokens = segmenter.process(str, JiebaSegmenter.SegMode.SEARCH);

        for (int i = 0; i < tokens.size(); i++) {
            char c = tokens.get(i).word.getToken().charAt(0);
            if (c <= 'A' || c > 'z') {
                continue;
            }
            if ("spring".equalsIgnoreCase(tokens.get(i).word.getToken())) {
                continue;
            }
            if (SpringFamily.contains(tokens.get(i).word.getToken())) {
                map.put("Spring" + tokens.get(i).word.getToken(), map.get(tokens.get(i).word.getToken()) == null ? 1 : map.get(tokens.get(i).word.getToken()) + 1);
                continue; 

            }
            map.put(tokens.get(i).word.getToken(), map.get(tokens.get(i).word.getToken()) == null ? 1 : map.get(tokens.get(i).word.getToken()) + 1);
        }
        ObjectMapper mapper = new ObjectMapper();
        String s = null;
        try {
            s = mapper.writeValueAsString(map);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

    }

    public List<StationInfo> getAllStationList() {
        return stationInfoMapper.queryAll();

    }


    public HashMap<String, Integer> getAllProvinceFrequency() {
        HashMap<String, Integer> map = new HashMap<>();
        List<String> stationInfos = stationInfoMapper.queryAllCities();
        for (int i = 0; i < stationInfos.size(); i++) {
            String position = stationInfos.get(i);
            String[] areas = position.split("-");
            if (!map.containsKey(areas[0])) {
                map.put(areas[0], 1);
            } else {
                map.put(areas[0], map.get(areas[0]) + 1);


            }


        }
        HashMap<String, Integer> resultMap = new HashMap<>();
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Integer> next = iterator.next();
            String province = (String) redisTemplate.opsForHash().get("city_info", next.getKey() + "市");
            if (resultMap.containsKey(province)) {
                resultMap.put(province, resultMap.get(province) + next.getValue());
            } else {
                if (province==null) continue;
                resultMap.put(province, next.getValue());
            }


        }

        HashMap<String, Integer> result = toLowerName(resultMap);
        return result;

    }

    private HashMap<String, Integer> toLowerName(HashMap<String, Integer> resultMap) {
        Set<String> keys = resultMap.keySet();
        HashMap<String, Integer> after = new HashMap<>();
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            if("内蒙古自治区".equals(key)){
                after.put("内蒙古",resultMap.get(key));
                continue;
            }
            if ("黑龙江省".equals(key)) {
                after.put("黑龙江",resultMap.get(key));
                continue;
            }
            after.put(key.substring(0,2),resultMap.get(key));

        }
        return after;

    }



    public FrequencyArraysVo getArrayOfProvinceFrequency() {

        HashMap<String, Integer> map = getAllProvinceFrequency();
        List<EchartsVo> echartsVos = EchartsUtil.mapToList(map);
        //排序
        Collections.sort(echartsVos, new Comparator<EchartsVo>() {
            @Override
            public int compare(EchartsVo o1, EchartsVo o2) {
                return o2.getValue() - o1.getValue();
            }
        });
        int size = echartsVos.size();
        String[] xdata = new String[size];
        Integer[] ydata1 = new Integer[size];
        for (int i = 0; i < size; i++) {
            xdata[i] = echartsVos.get(i).getName();
            ydata1[i] = echartsVos.get(i).getValue();
        }
        FrequencyArraysVo vo = new FrequencyArraysVo(xdata,new FrequencyArraysVo.yData(ydata1));
        return vo;

    }

    public HashMap<String, Integer> getAllEducationFrequency() {
        String s = redisTemplate.opsForValue().get(AppRedisKey.ALL_EDUCATION_FREQUENCY);
        if (s!=null) {
            return JSON.parseObject(s, HashMap.class);
        }
        List<String> words = analyseDataMapper.queryAllEducation();
        HashMap<String, Integer> result = StatisticFrequency(words, 0);
        redisTemplate.opsForValue().set(AppRedisKey.ALL_EDUCATION_FREQUENCY,JSON.toJSONString(result),1, TimeUnit.HOURS);
        return result;
    }

    public HashMap<String, Integer> getAllExperienceFrequency() {
        String s = redisTemplate.opsForValue().get(AppRedisKey.ALL_EXPERIENCE_FREQUENCY);
        if (s!=null) {
            return JSON.parseObject(s, HashMap.class);
        }
        List<String> words = analyseDataMapper.queryAllExperience();
        HashMap<String, Integer> result = StatisticFrequency(words, 0);
        redisTemplate.opsForValue().set(AppRedisKey.ALL_EXPERIENCE_FREQUENCY,JSON.toJSONString(result),1, TimeUnit.HOURS);
        return result;
    }

    static HashMap<String, Integer> StatisticFrequency(List<String> words, int threshold) {
        HashMap<String, Integer> map = new HashMap<>();

        for (int i = 0; i < words.size(); i++) {
            String key = words.get(i);
            if (!map.containsKey(key)) {
                map.put(key, 1);
            } else {
                map.put(key, map.get(key) + 1);
            }
        }
        HashMap<String, Integer> result = new HashMap<>();
        Set<String> strings = map.keySet();
        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            int fre = map.get(key);
            if (fre >= threshold) {
                result.put(key, fre);
            }
        }
        return result;
    }
}